import 'package:flutter/material.dart';

import 'styles.dart';
import 'text_theme.dart';

class CoreTheme extends InheritedTheme {
  CoreTheme({
    required Brightness brightness,
    required Color primaryColor,
    required Color primaryContrastingColor,
    required super.child,
    super.key,
  })  : _brightness = brightness,
        _primaryColor = primaryColor,
        _primaryContrastingColor = primaryContrastingColor,
        _data = _buildThemeData(
          brightness: brightness,
          primaryColor: primaryColor,
          primaryContrastingColor: primaryContrastingColor,
        );

  final Brightness _brightness;
  final Color _primaryColor;
  final Color _primaryContrastingColor;
  final CoreThemeData _data;

  static CoreThemeData _buildThemeData({
    required Brightness brightness,
    required Color primaryColor,
    required Color primaryContrastingColor,
  }) {
    return switch (brightness) {
      Brightness.dark => CoreThemeData.dark(
        primaryColor: primaryColor,
        primaryContrastingColor: primaryContrastingColor,
      ),
      Brightness.light => CoreThemeData.light(
        primaryColor: primaryColor,
        primaryContrastingColor: primaryContrastingColor,
      ),
    };
  }

  static CoreThemeData of(BuildContext context) {
    final inheritedTheme = context.dependOnInheritedWidgetOfExactType<CoreTheme>()!;
    return inheritedTheme._data;
  }

  @override
  Widget wrap(BuildContext context, Widget child) {
    final ancestorTheme = context.findAncestorWidgetOfExactType<CoreTheme>();

    if (identical(this, ancestorTheme)) {
      return child;
    }

    return CoreTheme(
      brightness: _brightness,
      primaryColor: _primaryColor,
      primaryContrastingColor: _primaryContrastingColor,
      child: child,
    );
  }

  @override
  bool updateShouldNotify(CoreTheme oldWidget) {
    return _brightness != oldWidget._brightness ||
        _primaryColor != oldWidget._primaryColor ||
        _primaryContrastingColor != oldWidget._primaryContrastingColor;
  }
}

class CoreThemeData {
  const CoreThemeData._internal({
    required this.brightness,
    required this.primaryColor,
    required this.primaryContrastingColor,
    required this.backgroundColor,
    required this.navigationBarColor,
    required this.dividerColor,
    required this.tileColor,
    required this.pressedTileColor,
    required this.tileNavigationIndicatorColor,
    required this.tilePlaceholderColor,
    required this.unselectedCheckboxBorderColor,
    required this.lexicalItemCardShadows,
    required this.overlayButtonShadows,
    required this.successIndicatorColor,
    required this.successIndicatorBackgroundColor,
    required this.failureIndicatorColor,
    required this.failureIndicatorBackgroundColor,
    required this.activityIndicatorColor,
    required this.activityIndicatorBackgroundColor,
    required this.progressIndicatorBackgroundColor,
    required this.textTheme,
  });

  factory CoreThemeData.light({
    required Color primaryColor,
    required Color primaryContrastingColor,
  }) {
    return CoreThemeData._internal(
      brightness: Brightness.light,
      primaryColor: primaryColor,
      primaryContrastingColor: primaryContrastingColor,
      backgroundColor: CoreStyles.lightGrey1,
      navigationBarColor: Colors.white,
      dividerColor: CoreStyles.lightGrey2,
      tileColor: Colors.white,
      pressedTileColor: CoreStyles.lightGrey2,
      tileNavigationIndicatorColor: CoreStyles.lightGrey4,
      tilePlaceholderColor: CoreStyles.lightGrey4,
      unselectedCheckboxBorderColor: CoreStyles.grey2,
      lexicalItemCardShadows: const [
        BoxShadow(
          color: CoreStyles.lightGrey5,
          blurRadius: 5.0,
          spreadRadius: 1.0,
        ),
      ],
      overlayButtonShadows: const [
        BoxShadow(
          color: Color(0x60000000),
          blurRadius: 30.0,
          spreadRadius: 0.0,
        ),
      ],
      successIndicatorColor: CoreStyles.darkGrey1,
      successIndicatorBackgroundColor: CoreStyles.lightGrey2,
      failureIndicatorColor: CoreStyles.darkGrey1,
      failureIndicatorBackgroundColor: CoreStyles.lightGrey2,
      activityIndicatorColor: CoreStyles.darkGrey1,
      activityIndicatorBackgroundColor: CoreStyles.lightGrey2,
      progressIndicatorBackgroundColor: CoreStyles.lightGrey2,
      textTheme: CoreTextTheme.light(
        primaryColor: primaryColor,
        primaryContrastingColor: primaryContrastingColor,
      ),
    );
  }

  factory CoreThemeData.dark({
    required Color primaryColor,
    required Color primaryContrastingColor,
  }) {
    return CoreThemeData._internal(
      brightness: Brightness.dark,
      primaryColor: primaryColor,
      primaryContrastingColor: primaryContrastingColor,
      backgroundColor: Colors.black,
      navigationBarColor: CoreStyles.darkGrey4,
      dividerColor: CoreStyles.darkGrey2,
      tileColor: CoreStyles.darkGrey3,
      pressedTileColor: CoreStyles.darkGrey2,
      tileNavigationIndicatorColor: CoreStyles.grey5,
      tilePlaceholderColor: CoreStyles.grey2,
      unselectedCheckboxBorderColor: CoreStyles.grey1,
      lexicalItemCardShadows: const [],
      overlayButtonShadows: const [
        BoxShadow(
          color: CoreStyles.darkGrey4,
          blurRadius: 30.0,
          spreadRadius: 0.0,
        ),
      ],
      successIndicatorColor: CoreStyles.lightGrey2,
      successIndicatorBackgroundColor: CoreStyles.darkGrey2,
      failureIndicatorColor: CoreStyles.lightGrey2,
      failureIndicatorBackgroundColor: CoreStyles.darkGrey2,
      activityIndicatorColor: CoreStyles.lightGrey2,
      activityIndicatorBackgroundColor: CoreStyles.darkGrey2,
      progressIndicatorBackgroundColor: CoreStyles.grey5,
      textTheme: CoreTextTheme.dark(
        primaryColor: primaryColor,
        primaryContrastingColor: primaryContrastingColor,
      ),
    );
  }

  final Brightness brightness;
  final Color primaryColor;
  final Color primaryContrastingColor;
  final Color backgroundColor;
  final Color navigationBarColor;
  final Color dividerColor;
  final Color tileColor;
  final Color pressedTileColor;
  final Color tileNavigationIndicatorColor;
  final Color tilePlaceholderColor;

  final Color unselectedCheckboxBorderColor;

  final List<BoxShadow> lexicalItemCardShadows;
  final List<BoxShadow> overlayButtonShadows;

  final Color successIndicatorColor;
  final Color successIndicatorBackgroundColor;
  final Color failureIndicatorColor;
  final Color failureIndicatorBackgroundColor;
  final Color activityIndicatorColor;
  final Color activityIndicatorBackgroundColor;

  final Color progressIndicatorBackgroundColor;

  final CoreTextTheme textTheme;
}
